package provider

import (
	"fmt"
	"ginfwk/framework/core/gins"
	"ginfwk/infrastructure/helper/gruntime"
	"github.com/gin-gonic/gin"
	di "github.com/samber/do"
	"strings"
)

func GinDebugPrintRegister() {
	di.Provide(di.DefaultInjector, func(*di.Injector) (gins.GinRoutePrintRegister, error) {
		return RegisterDebugPrintRoute, nil
	})
}

// RegisterDebugPrintRoute register custom gin router printer
func RegisterDebugPrintRoute(g gins.IEngine) {
	gin.DebugPrintRouteFunc = func(httpMethod, absolutePath, handlerName string, nuHandlers int) {
		handlerName = getHandlerName(g, httpMethod, absolutePath)
		ginDebugPrint("%-6s %-25s --> %s (%d handlers)\n", httpMethod, absolutePath, handlerName, nuHandlers)
	}
}

// ginDebugPrint custom definition of gin router printer
func ginDebugPrint(format string, values ...any) {
	if gin.IsDebugging() {
		if !strings.HasSuffix(format, "\n") {
			format += "\n"
		}
		fmt.Fprintf(gin.DefaultWriter, "[GIN-debug] "+format, values...)
	}
}

// getHandlerName get handler from the registered routes
func getHandlerName(g gins.IEngine, httpMethod string, absolutePath string) string {
	routeInfo, ok := g.GetRouteInfo(httpMethod, absolutePath)
	if !ok || len(routeInfo.Handlers) <= 0 {
		// return the default text "-------" if the route info or handler is not found.
		return strings.Repeat("-", 6)
	}

	handler := routeInfo.Handlers[len(routeInfo.Handlers)-1]
	return gruntime.NameOfFunction(handler)
}
